package com.wangzhen.codebase.thread.state;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MyQueueDemo<T> {

    private int length;

    private int index;

    private Object[] elements = null;

    public MyQueueDemo(Integer length) {
        this.length = length;
        elements = new Object[10];
    }

    /**
     * 提供一个加入队列的方法
     * @param t
     */
    public void offer(T t) {
        synchronized (this) {
            while (index + 1 > length) {
                try {
                    System.out.println("当前队列已经满了！！！"+ index);
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("现在队列不满，可以添加数据了！！！"+index);
            // 将数据保存在currentPosition 上
            elements[(index+1 == length) ? index : index++] = t;
            // notifyAll一下，防止有人在等待取数据；
            this.notifyAll();
        }
    }

    /**
     *
     */
    public T peek() {
        synchronized (this) {
            while (index == 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 保存本次要返回的结果
            T result = (T)elements[0];
            // 3.2、数据移动，把index从（1-length）之间的数据向左挪动一个位置；
            // 3.3、currentPosition--
            System.arraycopy(elements, 1, elements, 0, --index);
            // 3.4、notifyAll一下 ，通知一下要插数据的线程
            this.notifyAll();

            return (T)elements[0];
        }
        // 1、每次只取下标为0位置上的数据；
        // 2、如果index=0上面的数据为null，说明当前队列为空，需要wait
        // 3、如果index=0上面的数据不为null，
        // 3.1、返回这个数据
        // 3.2、数据移动，把index从（1-length）之间的数据向左挪动一个位置；
        // 3.3、currentPosition--
        // 3.4、notifyAll一下 ，通知一下要插数据的线程；
    }

    public static void main(String[] args) {
        MyQueueDemo<String> queue = new MyQueueDemo<>(10);
        //
        Thread t1 = new Thread(()->{
            while (true) {
                queue.offer(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
        });

        Thread t2 = new Thread(()->{
            while (true) {
                System.out.println(queue.peek());
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                }
            }
        });

        t1.start();
        t2.start();

    }
}
